<?php

class Quad_FrontController extends Quad_Observable implements Quad_FrontController_Interface, Quad_Mvc_Interface {
	 
	public $_bootstrap;
	
  public function __construct(Quad_Bootstrap_Interface $bootstrap) {
    $this->_bootstrap = $bootstrap;
  }
	
  public function dispatch() {
  	try {
	  	$router = $this->getRouter();
			$router->requireControllerClass();
  		$method = $router->getActionMethod();
  		
			$controller = $this->getController();
	  	$controller->preDispatch();
	  	$controller->$method();
	  	$controller->postDispatch();
			$postProcessor = array($controller, 'postProcess' . ucwords($this->getBootstrap()->runType));
			if (is_callable($postProcessor)) {
				call_user_func($postProcessor);
			}
			$this->getView()->render();
  	}
  	catch (Quad_FrontController_Forward $e) {
  		// we have forwarded to another controller and/or action
  		$this->dispatch();
  	}
  	catch (Quad_FrontController_Redirect $e) {
  		// we have encountered a "virtual redirect" as in a unit-test environment
  		$this->getBootstrap()->teardown();
  		$_SERVER['REQUEST_URI'] = $e->url;
  		$this->getBootstrap()->run();
  	}
		catch (Quad_Exception $e) {
			
		}
		catch (Exception $e) {
			
		}
  }
	
	public function getFrontController() {
		return $this;
	}
	
	public function getBootstrap() {
		return $this->_bootstrap;
	}
	
	public function getView() {
		return $this->getController()->getView();
	}
	
	public function getController() {
		if (!$this->_controller) {
			$router = $this->getRouter();
			$router->requireControllerClass();
  		$class = $router->getControllerClass();
  		$this->_controller = new $class($this);
		}
		return $this->_controller;
	}
	
  public function getRouter() {
    return $this->getBootstrap()->getRouter();
  }    	
  
	public function getUrl() {
		return $this->getBootstrap()->getUrl();
	}
	
}